//将开发模式和生成模式下的公共webpack配置抽到这里，然后不同的配置分别放在webpack.devconfig.js文件和webpack.proconfig.js下。
const eslintplugin = require('eslint-webpack-plugin')
const minicss =require('mini-css-extract-plugin')
const minimizer = require('css-minimizer-webpack-plugin')
const htmlwebpackplugin = require('html-webpack-plugin')
const bundleanlyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const MyCustomPlugin = require('./MyCustomPlugin');;//自定义插件


console.log(process.env.NODE_ENV)
let plugins = [
  //注册eslint插件
  // new eslintplugin({}),

  //注册压缩CSS的插件
  new minimizer(),
  
  //注册HTML插件
  new htmlwebpackplugin({
    //template和templateContent都是模板，template是通过url方式引入模板，templateContent则是通过函数返回。
    template:'./index.html',
    // templateContent:function(){
    //   return '<div><div>'
    // },
    filename:"index.html",
    //压缩相关的配置
    minify:{
      //是否移出空格换行(默认值为true)
      collapseWhitespace:false,
      //是否移出注释(默认值为true)
      removeComments:false,
      //属性之间是否清除空格(默认值为true)
      removeAttributeQuotes:false,
    },
    //js加载的位置 body  head  false(不引入)
    inject:'body',
    //在index.html中e.js的变量
    title:'你好',
    arr:[{title:"第一"}, {title:"第二"}, {title:"第三"},]
  }),

  //注册可视化打包插件
  new bundleanlyzer(),

  //注册自定义插件
  new MyCustomPlugin({ /* 传递选项 */ })
]
//判断是否是开发模式 是的话则注册minicss插件
function hasMiniCss(){
  if(process.env.NODE_ENV=='production'){
    plugins.push(
      //注册minicss插件
      new minicss({
        filename:'./css/test.[contenthash:4].css'//打包出的CSS文件名  放在dist文件夹下的css文件夹里
      })
    )
  }
}
hasMiniCss()

module.exports = {
  // mode:"development",//production生产模式 (打包会压缩文件) development开发模式() none(什么都不做)
  // devtool:'eval-cheap-source-map',//‘eval-cheap-source-map’便于浏览器F12查看源码时，是原代码而非打包后的代码。默认值为none代表打包代码。
  optimization:{
    //代码分割
    splitChunks:{
      /*chunks的取值有三种，
      'all'对所有类型的模块进行拆分；设置为 all 可能特别强大，因为这意味着 chunk 可以在异步和非异步 chunk 之间共享
      'async'动态引入的模块将会被拆分，多入口时：两个入口文件异步引入c文件时，会打包成一个文件复用
      'initial'  在单入口时与all没什么区别，但多文件入口时，不会将动态引入和静态引入的同一模块一起处理，而是分开处理；
      */
      chunks:'all',
      //一个文件出现多少次才会拆分出单独文件，而不用被打包进去。
      minChunks:1,
      //文件大于该值才会拆分 单位byte
      minSize:1,
      // minChunks: 1, // 文件至少被 1 个chunk 引用
      maxAsyncRequests: 7, // 动态导入文件最大并发请求数为 7,意思最后打包出的文件算上异步的最多不能超过7
      maxInitialRequests: 5, // 也就是每个入口和它的同步依赖最多够被拆分/合并成几个js文件。对这个数量进行限制为的是避免初始js请求过多。入口文件本身算一个请求，单独拆出的runtimeChunk和css文件，不算在内  

      // automaticNameDelimiter: '~', // 文件名中的分隔符
      //打包出的文件名  设置为true则自动命名
      // name:'chunkCode',
      cacheGroups: {
        // chunks:'all',
        vendors: { // vendors用于提取所有node_modules中符合条件的模块
          test: /[\\/]node_modules[\\/]/,
          filename:'vendor.[chunkhash:4].js',
          priority: 50 // 当一个模块同时符合多个cacheGroups时，则根据其中的priority配置项确定优先级
        },
        common: { // 作用于被多次引用的模块
          filename:'[name].[chunkhash:4].js',
          // chunks:'all',
          minChunks: 2,
          minSize:1,
          priority: 30,
          reuseExistingChunk: true//复用其他chunk内已拥有的模块 当chunks引用了已经存在的被抽离的chunks时不会新创建一个chunk而是复用chunk
        }
      },
    },
    //runtimeChunk用于控制运行时代码的提取和生成。运行时代码包含了 webpack 运行时所需的逻辑，例如模块解析、模块加载等。将运行时代码提取为单独的 chunk 可以帮助实现更好的缓存策略，避免因业务代码变化而导致运行时代码变动而无法利用缓存的情况。
    runtimeChunk:{
      name:'runtime'
    }
  },

  /*
  单入口文件写法
  entrt:'./app.js',
  */
  /*
  多文件一个入口写法
  entrt:[ './app1.js', './app1.js']
  */
  /*
  多入口多文件写法
  entrt:{
    app1:[ './app1.js', './app1.js'],
    app2:'./app3.js'
  }
  */
  entry:{
    app:'./app.js',
    app2:'./app2.js'
  },

  // 出口 即打包后包的位置
  output:{
    path: __dirname+'/dis', 
    //filename包的文件名  [name]入口的名字(即app1，这样多于多入口文件可以避免同名覆盖) [hash:4]哈希值四位
    filename:'[name].[chunkhash:4].budle.js',
    // publiPath:'www.xxx.com'//cdn路径
  },

  devServer:{
    port:5000,//端口5000
    hot:true,//热更新 
  },
  resolve:{
    alias: {
      '@css':'/css'
    },
    extensions:['.js','.css','.json']//省略后缀
  },

  //loader
  module:{
    //数组里每一个对象就是一个loader
    rules:[
      {
        test: /\.js$/,
        //不处理node_modules目录下的文件
        exclude: /node_modules/,
        //use字段指定了要使用的loader和参数。
        use: {
          //使用babel-loader进行转译。
          loader:'babel-loader',
          //options字段指定了babel-loader的选项，其中包含了转译时使用的预设(preset)。
          //options配置项可以写在.babelrc文件下，也可以写在options对象里，此处注释options对象里的，使用.babelrc文件下的
          // options:{
          //   presets:[
          //     [
          //       '@babel/preset-env',
          //       {
          //         targets:{
          //           browsers:[
          //             '>1%',
          //             'last 2 versions',
          //             'not ie<=8'
          //           ]
          //         }
          //       }
          //     ]
          //   ]
          // }
        }
      },
      //处理css文件
      {
        test: /\.css/,
        // use: ['style-loader',"css-loader"],//使用'style-loader'  "css-loader"  './mycss-loader'是自定义loader
        use: [ 
          process.env.NODE_ENV=='production'?minicss.loader:"style-loader",//通过环境变量判断是否是生成环境是的话则使用minicss.loader来压缩CSS代码
          "css-loader",
          './mycss-loader'
        ]//使用minicss.loader,"css-loader"
      },
      //处理less文件
      {
        test: /\.less/,
        use: [
          process.env.NODE_ENV=='production'?minicss.loader:"style-loader",
          "css-loader",
          'less-loader']
      },
      /*   webpack4的图片处理
      //图片处理
      {
        test: /\.(jpg|jpeg|png|gif|svg)$/,
        loader:'url-loader',
        options:{
          //文件小于limit(2000 字节约等于 2KB)值得转换为base64
          limit:2000,
          name:'[name].[hash:4].[ext]'
        }
      },
      */

     //webpage5的图片处理（使用自带的）
      {
        test: /\.(jpg|jpeg|png|gif|svg)$/,
        /*
        type值常见的有以下三种
        'asset/inline' 使用图片都会转换为base64  
        'asset/resource'则是使用图片都生成独立文件  
        'asset'则相当于智能的选择,可通过parser来配置要转换的要求
        */
        type:'asset',
        parser:{
          dataUrlCondition:{
            //文件大于20字节的生成独立文件，不转base64
            maxSize:20
          }
        },
        generator:{
          filename: "./img/[name].[contenthash:4].[ext]"
        }
      }
    ]
  },
  //插件
  plugins:plugins,
}